package com.sanri.tools.modules.mock.l7.websocket.chat.service.ws;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sanri.tools.modules.core.security.UserService;
import com.sanri.tools.modules.core.security.dtos.ThinUser;
import com.sanri.tools.modules.mock.l7.websocket.chat.service.ws.message.SocketMessageCommand;
import com.sanri.tools.modules.mock.l7.websocket.chat.service.ws.message.UnBindMessageHandler;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Slf4j
public class ChatWebsocketServer extends WebSocketServer {

    /**
     * 消息处理器
     */
    private Map<String, SocketMessageCommand.MessageHandler> messageHandlerMap = new HashMap<>();

    public ChatWebsocketServer() {
        super(new InetSocketAddress(10090));
    }

    @Override
    public void onOpen(WebSocket conn, ClientHandshake handshake) {
    }

    @Override
    public void onClose(WebSocket conn, int code, String reason, boolean remote) {
        Iterator<Map.Entry<String, ChatSession>> iterator = ChatSupport.sessionMap.entrySet().iterator();
        while (iterator.hasNext()){
            Map.Entry<String, ChatSession> next = iterator.next();
            boolean equals = next.getValue().getWebSocket().equals(conn);
            if (equals){
                log.info("[下线]{}",next.getKey());
                iterator.remove();

                SocketMessageCommand.MessageHandler messageHandler = messageHandlerMap.get("chat/unbind");
                if (messageHandler != null ){
                    UnBindMessageHandler.BindMessage bindMessage = new UnBindMessageHandler.BindMessage();
                    String token = next.getValue().getToken();
                    bindMessage.setCommand("chat/unbind");
                    bindMessage.setToken(token);
                    try {
                        messageHandler.handle(conn , JSON.toJSONString(bindMessage));
                    } catch (IOException e) {
                        log.error("发布下线消息失败: {}", e.getMessage(), e);
                    }
                }
            }
        }
    }

    /**
     * @param conn
     * @param message
     */
    @SneakyThrows
    @Override
    public void onMessage(WebSocket conn, String message) {
        JSONObject jsonObject = JSON.parseObject(message);

        String command = jsonObject.getString("command");
        SocketMessageCommand.MessageHandler messageHandler = messageHandlerMap.get(command);
        if (messageHandler != null){
            messageHandler.handle(conn, message);
        }else {
            log.error("不支持的指令: {}", command);
        }
    }

    @Override
    public void onError(WebSocket conn, Exception ex) {

    }

    @Override
    public void onStart() {

    }

    public void setMessageHandlerMap(Map<String, SocketMessageCommand.MessageHandler> messageHandlerMap) {
        this.messageHandlerMap = messageHandlerMap;
    }
}
